Skip to content

#8 Provider/Tunnel 稳定持久 id:凭证与可编辑字段解耦 - #26

Merged
benz-ai-x merged 5 commits into
mainfrom
fix/issue-8-stable-identity
Aug 20, 2026
Merged

#8 Provider/Tunnel 稳定持久 id:凭证与可编辑字段解耦#26
benz-ai-x merged 5 commits into
mainfrom
fix/issue-8-stable-identity

Conversation

@benz-ai-x

Copy link
Copy Markdown
Owner

摘要

  • Tunnel t-<sha1 身份> / Provider p-<sha1 名> 装载期确定性赋 id(幂等;重复身份/id 可行动报错不猜 secret)
  • Keychain 账户 tunnel:<id> 寻址 + legacy 回退读 + 双账户删除;rename/改地址不丢凭证
  • _restore_key 按 id 匹配(重命名保 key;id 不同绝不按名串接;legacy 无 id 档按名回退)
  • prepare re-pin:legacy 密码随下次提交迁到 id 账户(复用 [P0][配置存储] 建立 MP/SP/Keychain 事务边界并保护最后已知良好配置 #6 事务的 keychain 计划与清理)
  • JS snapshot 直通 id(id 变更=dirty)

验收对照

  • 新建实体稳定 id;重命名/改地址不变不丢凭证
  • 旧格式确定性迁移;同名/重复身份失败+可行动信息
  • keep/replace/clear 三态 rename 后正确(id 不同不串接)
  • Tunnel 身份编辑后新账户读原 secret;旧条目随完整提交清理(re-pin+双账户删除)
  • 删除按明确策略清理(双账户)、失败可重试不误删
  • UI snapshot 直通 id;id 变更纳入 dirty
  • migration/rename/collision/round-trip 测试
  • ADR-002 增补

pytest 1418 + node 94;Closes #8

🤖 Generated with Claude Code

benz-ai-x and others added 5 commits August 20, 2026 13:58
- Tunnel:装载期确定性赋 id(t-<sha1 身份>,assign_stable_ids);
  重复身份/重复 id 可行动报错;重命名/改地址不改 id
- Keychain:账户优先 tunnel:<id>;legacy user@host:port 作迁移期回退读;
  set 只写 id 账户;delete 双账户清理(新+legacy)
- Provider:装载期确定性赋 id(p-<sha1 名>,幂等);_restore_key 按 id
  匹配——重命名保住 key;id 不同绝不按名串接(仅 legacy 无 id 档按名
  回退)
- prepare re-pin:password 隧道无新密时经 legacy 回退读旧密码迁到 id
  账户,旧条目随事务双账户清理(复用 #6 的 keychain_sets/dels 计划)
- JS:providers/tunnels snapshot 直通 id(id 变更=dirty;collect 原地
  改不改 id)
- 测试:确定性/幂等迁移、重复报错、rename 保 key、id 不同不串接、
  clear 语义、re-pin、装载即赋
- ADR-002 增补稳定 id 与凭证所有权

pytest 1418 + node 94 全绿。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- prepare(sp=) 承接 _restore_masked_sp_keys:live PUT 唯一保存路径此前
  不经 save_config_dict,api_key keep/replace/clear 在真实链路丢失
  (掩码回传会把真实 key 擦成 null——数据丢失级 bug,一审抓出)
- re-pin 串线守卫:只在 id==stable_tunnel_id(当前身份) 时读 legacy——
  Y 改址到 X 旧地址不再串走 X 的密码;收敛补齐(legacy-only 删除
  keychain.delete_legacy_password,随事务完成,不再每次保存重复 re-pin)
- 删除隧道:prepare diff 旧档 → kc_dels 双账户清理(此前删除残留 secret)
- IdentityMigrationError 专属类型:迁移错误不再被吞成 .bak 隔离或 500
  (mp 侧上抛不隔离;sp 侧 load_config_masked 降级 _load_error 供 UI)
- JS rename 撞名守卫:目标名已被占用即拒绝并提示(不再静默覆盖丢实体)
- keychain._account 复用 _legacy_account(去逐字重复)

pytest 1420 全绿。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- legacy 同身份双隧道(key+password 并存)本合法:确定性序数后缀
  区分 id(#2 后缀,重算同序),共享 legacy 凭证槽与迁移前一致,
  不拒启不猜归属;显式手写重复 id 仍致命
- app.py 启动迁移错 → rumps 弹窗可行动指引后退出(原文件未动)
- _read_mp 迁移错降级 _load_error 空态(/api/state 不 500)
- _load_error 三带消费:JS validateConfig 阻断保存(+测试);
  prepare 拒收带标记候选(+测试);_restore_masked_sp_keys 剥离
  防落盘残留(+直测)——覆盖丢档路径全封死

pytest 1422 + node 85 全绿。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- mp 侧 _load_error 补 JS validateConfig 阻断 + prepare 拒收双带
  (降级空态不再可能被保存覆盖原档)
- assign_stable_ids 显式 id 分支登记 seen_identity + 分配后查重:
  已迁移 A + 手工同身份无 id B → B 得序数后缀 id,绝不静默同 id
  串钥匙串

pytest 1425 + node 95 全绿。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
同 commit 新增的 ident-in-seen_identity raise 误杀合法状态:legacy 双
身份迁移后两条带 id,重载即触发 → _load_error 空态 + 拒收 = 永久锁死。
id 撞车已由 seen_ids 查重与分配后查重覆盖,该 raise 冗余且有害。

补幂等重载回归测试(迁移后带 id 重载 n=0 不 raise)。

pytest 1426 全绿。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@benz-ai-x
benz-ai-x merged commit 896f3a4 into main Aug 20, 2026
0 of 4 checks passed
@benz-ai-x
benz-ai-x deleted the fix/issue-8-stable-identity branch August 20, 2026 06:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[P1][持久化身份] 解除名称/地址编辑与 Provider、Tunnel 凭证绑定

1 participant